<template>
  <div class="container" id="container">
    <u-upload
      ref="uploadRef"
      :action="action"
      :file-list="fileList"
      :form-data="formData"
      :auto-upload="false"
      :before-upload="beforeUpload"
      :max-size="10485760"
      :max-count="maxImageCount"
      :size-type="sizeType"
      :limitType="['png', 'jpg', 'jpeg']"
      :height="uploadItemWidth"
      @on-choose-complete="onChooseComplete"
      @on-list-change="onListChange"
      @on-success="onUploadSuccess"
      @on-uploaded="onUploaded"
      @on-error="onError"
      @on-remove="onRemove" />
  </div>
</template>

<script setup lang="ts">
  import {systemApi} from '@/service/api'
  import {getNoSymbolUuid} from '@/common/utils'

  interface UploadGroupProps {
    width: number
    maxImageCount: number | string
    uploadImageDir: string
    uploadId?: string
    sizeType?: Array<'original' | 'compressed'> | any
    fileList?: Array<any> | any
  }

  const props = withDefaults(defineProps<UploadGroupProps>(), {
    maxImageCount: 9,
    sizeType: ['original', 'compressed'],
    fileList: []
  })

  const emit = defineEmits(['onChooseComplete', 'onImageUploaded', 'onRemoveImage', 'onUploadError','onListChange'])

  const uploadRef = ref<any>(null)

  const uploadItemWidth = ref(0)
  const action = ref<string | undefined>('')
  const tempFinalSrc = ref<string>('')
  const imageList = ref<Array<string>>([])
  const formData = ref<Object>({})
  let isError = false

  // 执行上传
  const upload = () => {
    uploadRef.value.upload()
  }

  defineExpose({upload, imageList})

  
  /**
   * 单个文件上传成功后回调
   * @param lists 当前文件列表
   */
  function onChooseComplete(lists:any) {
    emit('onChooseComplete', lists)
  }
  /**
   * 单个文件上传成功后回调
   * @param lists 当前文件列表
   */
  function onListChange(lists:any) {
    emit('onListChange', lists)
  }

  /**
   * 单个文件上传成功后回调
   * @param data 上传文件成功后的响应
   * @param listsIndex 上传文件信息列表下标
   * @param lists  上传文件信息列表
   */
  function onUploadSuccess(data: any, listsIndex: any, lists: any) {
    tempFinalSrc.value = data.url
    imageList.value.push(tempFinalSrc.value)
  }

  // 所有图片上传成功后的回调
  function onUploaded(lists: any) {
    if (isError) return emit('onUploadError')
    emit('onImageUploaded', imageList.value)
  }

  /**
   * 上传文件前回调
   * @param listsIndex 上传文件信息列表下标
   * @param lists 上传文件信息列表
   */
  function beforeUpload(listsIndex: any, lists: any): Promise<void | string> {
    return new Promise<void | string>((resolve, reject) => {
      const dir = props.uploadImageDir
      const tempPath = lists[listsIndex].file.path
      const fileSuffix = tempPath.substr(tempPath.lastIndexOf('.'))
      systemApi.getUploadSignature({targetTypeName: dir}).then((res) => {
        const signData = res.data // 拿到后端返回数据
        action.value = `https://${signData?.uploadDomain}` //上传的url
        const key = `${signData?.keyPrefix}${getNoSymbolUuid()}${fileSuffix}` // 组合保存到云的文件路径
        if (res.success) {
          formData.value = {
            key: key,
            token: signData?.token
          }
          // tempFinalSrc.value = 'https://' + signData?.downloadDomain + '/' + key
          resolve()
        } else {
          reject()
          console.error('获取签名失败', res)
        }
      }).catch((err) => {
        console.error('getUploadSignature错误', err)
        uni.showToast({
          title: '网络异常',
          icon: 'error',
          duration: 3000
        })
      })
    })
  }

  /**
   * 错误发生的回调
   * @param err 错误原因
   * @param index 错误下标
   */
  function onError(err: any, index: any) {
    isError = true
    console.error('[图片上传]', `第${index}张图片上传失败`)
    throw err
  }

  /**
   * 移除图片的回调
   * @param listsIndex 移除图片列表下标
   * @param lists 当前文件列表
   */
  function onRemove(listsIndex: any, lists: any) {
    isError = false
    emit('onRemoveImage', listsIndex, lists)
  }

  onMounted(() => {
    uploadItemWidth.value = (props.width - 60) / 3 - 10
  })
</script>

<style scoped lang="scss">
  @import 'upload-group';
</style>